/*
 * CDPSAbilityCondition.java
 * 
 * Copyright (c) 2009 Giles Millward (Manigra). All rights reserved.
 * 
 * This file is part of JRogueDPS.
 * 
 * JRogueDPS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * JRogueDPS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with JRogueDPS.  If not, see <http://www.gnu.org/licenses/>.
 */

package dpsinterface;

import dpssystem.CSim;

/**
 *
 * @author Mani
 */
public class CDPSAbilityCondition {
    CBaseCondition m_condition;
    int m_valueInt;
    double m_valueDouble;

    CDPSAbilityCondition(String p_condition)
    {
        // Parse the condition string. The condition type will
        // define the class we need to use and the value type
        // to compare with.
        String l_tokens[] = p_condition.split("=");

        if (l_tokens.length != 2)
        {
            return;
        }

        String l_name = l_tokens[0];
        String l_value = l_tokens[1];

        if (l_name.equals("min_combo_points")) {
            m_valueInt = Integer.parseInt(l_value);
            m_condition = new CMinCPGreaterOrEqual();
        } else if (l_name.equals("max_combo_points")) {
            m_valueInt = Integer.parseInt(l_value);
            m_condition = new CMaxCPLessOrEqual();
        } else if (l_name.equals("cp>")) {
            m_valueInt = Integer.parseInt(l_value);
            m_condition = new CMinCPGreaterOrEqual();
        } else if (l_name.equals("cp<")) {
            m_valueInt = Integer.parseInt(l_value);
            m_condition = new CMaxCPLessOrEqual();
            
        } else if (l_name.equals("min_energy")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMinEnergyGreaterOrEqual();
        } else if (l_name.equals("max_energy")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMaxEnergyLessOrEqual();
        } else if (l_name.equals("energy>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMinEnergyGreaterOrEqual();
        } else if (l_name.equals("energy<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMaxEnergyLessOrEqual();
            
        } else if (l_name.equals("hfb>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMinHFBExpireGreaterOrEqual();
        } else if (l_name.equals("hfb<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMaxHFBExpireLessOrEqual();

        } else if (l_name.equals("snd>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMinSNDExpireGreaterOrEqual();
        } else if (l_name.equals("snd<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMaxSNDExpireLessOrEqual();

        } else if (l_name.equals("env>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMinEnvenomExpireGreaterOrEqual();
        } else if (l_name.equals("env<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMaxEnvenomExpireLessOrEqual();

        } else if (l_name.equals("rup>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMinRuptureExpireGreaterOrEqual();
        } else if (l_name.equals("rup<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CMaxRuptureExpireLessOrEqual();

        } else if (l_name.equals("sync")) {
            // TODO ?
            
        } else if (l_name.equals("time>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CTimeGreaterOrEqual();
        } else if (l_name.equals("time<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CTimeLessOrEqual();

        } else if (l_name.equals("time_to_die>")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CTimeToDieGreaterOrEqual();
        } else if (l_name.equals("time_to_die<")) {
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CTimeToDieLessOrEqual();

        } else if (l_name.equals("wait_on_ready")) {
            // TODO ??
        } else if (l_name.equals("min_doses")) {
            m_valueInt = Integer.parseInt(l_value);
            m_condition = new CMinDoses();

        } else if (l_name.equals("no_buff")) {
            m_valueInt = Integer.parseInt(l_value);
            m_condition = new CNoBuff();

        } else if (l_name.equals("refresh_at")) {
            // HFB only
            m_valueDouble = Double.parseDouble(l_value);
            m_condition = new CHFBRefreshAt();

        } else if (l_name.equals("wait")) {

        } else if (l_name.equals("for_next")) {

        }
    }

    public int getConditionCode(CSim p_sim)
    {
        return m_condition.getConditionCode(p_sim);
    }

    public abstract class CBaseCondition
    {
        public abstract int getConditionCode(CSim p_sim);
    }

    // Combo point conditions
    public class CMinCPGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_target.m_comboPoints.m_comboPoints >= m_valueInt) ? 1:0;
        }
    }

    public class CMaxCPLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_target.m_comboPoints.m_comboPoints <= m_valueInt) ? 1:0;
        }
    }

    // Energy conditions
    public class CMinEnergyGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_player.m_energyRegen.m_currentEnergy >= m_valueDouble) ? 1:0;
        }
    }

    public class CMaxEnergyLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_player.m_energyRegen.m_currentEnergy <= m_valueDouble) ? 1:0;
        }
    }

    // HFB Expiration conditions
    public class CMinHFBExpireGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            // TODO
            return 0;
        }
    }

    public class CMaxHFBExpireLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            // TODO
            return 0;
        }
    }

    // SND Expiration conditions
    public class CMinSNDExpireGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime - p_sim.m_player.m_sliceAndDice.getTimer() >= m_valueDouble) ? 1:0;
        }
    }

    public class CMaxSNDExpireLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime - p_sim.m_player.m_sliceAndDice.getTimer() <= m_valueDouble) ? 1:0;
        }
    }

    // Envenom Expiration conditions
    public class CMinEnvenomExpireGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime - p_sim.m_envenom.getTimer() >= m_valueDouble) ? 1:0;
        }
    }

    public class CMaxEnvenomExpireLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime - p_sim.m_envenom.getTimer() <= m_valueDouble) ? 1:0;
        }
    }

    // Rupture Expiration conditions
    public class CMinRuptureExpireGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime - p_sim.m_rupture.getTimer() >= m_valueDouble) ? 1:0;
        }
    }

    public class CMaxRuptureExpireLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime - p_sim.m_rupture.getTimer() <= m_valueDouble) ? 1:0;
        }
    }

    // Simulation Time conditions
    public class CTimeGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime >= m_valueDouble) ? 1:0;
        }
    }

    public class CTimeLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_currentRunTime <= m_valueDouble) ? 1:0;
        }
    }

    // Simulation Time conditions
    public class CTimeToDieGreaterOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_maxRunTime - p_sim.m_currentRunTime >= m_valueDouble) ? 1:0;
        }
    }

    public class CTimeToDieLessOrEqual extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_maxRunTime - p_sim.m_currentRunTime <= m_valueDouble) ? 1:0;
        }
    }

    // Min Doses
    public class CMinDoses extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (p_sim.m_target.m_deadlyPoisonDOT.m_stacks >= m_valueInt) ? 1:0;
        }
    }

    // No envenom buff
    public class CNoBuff extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            return (m_valueInt == 1 && p_sim.m_envenom.hasEnvenomBuff()) ? 0:1;
        }
    }

    // No envenom buff
    public class CHFBRefreshAt extends CBaseCondition
    {
        public int getConditionCode(CSim p_sim)
        {
            // TODO
            return 0;
        }
    }
}
